export interface FastWorkerOptions<Module extends Record<keyof any, any>> {
  /**
   * Maximum number of times to re execute when execution fails.
   * @default 0
   */
  maxRetries?: number
  /**
   * By default, the 'fast worker' task can be handed over to the main thread or the worker thread for execution.
   * Enable this option will force the task to be handed over to the worker thread for execution.
   *
   * Please set this to True if you are using es-module.
   */
  onlyExecInWorker?: boolean
  /**
   * Sets the timeout period to throw an exception if the task is not completed within the specified time.
   * @default 5000
   */
  timeout?: number | null
  /**
   * Set the retry interval.
   * @default 0
   */
  retryInterval?: number
  /**
   * init (NEW)
   */
  onInit?: (this: Omit<FastWorker<Module>, 'dispose' | 'disposed'>, worker: Omit<FastWorker<Module>, 'dispose' | 'disposed'>, isMainThread?: boolean) => void
  /**
   * init (NEW)
   */
  onCleanup?: (this: Omit<FastWorker<Module>, 'dispose' | 'disposed'>, worker: Omit<FastWorker<Module>, 'dispose' | 'disposed'>, isMainThread?: boolean) => void
}

type _StructuredBase<T> = Exclude<T, symbol | Function | ((...args: any[]) => any)>
type _Structured<T> = T extends Promise<infer R> ? Promise<_StructuredBase<R>> : _StructuredBase<T>

type FastWorkerPromisify<T extends Record<keyof any, any>> = {
  [method in keyof T & string]: T[method] extends (...args: infer P) => infer R
    ? (
        ...args: {
          [K in keyof P]: P[K] extends Promise<infer R> ? _StructuredBase<R> : P[K]
        }
      ) => Promise<Awaited<_Structured<R>>>
    : never
}

export type FastWorker<Module extends Record<keyof any, any>> = Omit<
  FastWorkerPromisify<Module>,
  'dispose' | 'disposed' | `_${string}`
> & {
  dispose(): void
  disposed: boolean
}
